/*
* @file    :drv_gpio.c
* @module  :GPIO
* @author  :LingFengLu
* @date    :2023-06-06
*/

#include "drv_gpio.h"

//Constant definition    宏定义
#define LED_1_PIN                    	GPIO_CHANNEL(PORT_B,PIN1)
#define LED_2_PIN                  	GPIO_CHANNEL(PORT_B,PIN4)
#define LED_3_PIN         		GPIO_CHANNEL(PORT_B,PIN2)

//Global variable definition    全局变量定义
typedef enum
{
	PULL_NO = LL_GPIO_PULL_NO,
	PULL_UP = LL_GPIO_PULL_UP,
	PULL_DOWN = LL_GPIO_PULL_DOWN,
}drv_gpio_pull;

//Private variable definition    私有变量定义
static uint32 AHB_PERIPH[PORT_COUNT] = {LL_AHB_PERIPH_GPIOA ,LL_AHB_PERIPH_GPIOB} ;
static GPIO_TypeDef*  Port[PORT_COUNT] = {GPIOA ,GPIOB} ;
static uint32 Pin[PIN_COUNT] = {
	LL_GPIO_PIN_0,LL_GPIO_PIN_1,LL_GPIO_PIN_2,LL_GPIO_PIN_3,
	LL_GPIO_PIN_4,LL_GPIO_PIN_5,LL_GPIO_PIN_6,LL_GPIO_PIN_7,
	LL_GPIO_PIN_8,LL_GPIO_PIN_9,LL_GPIO_PIN_10,LL_GPIO_PIN_11,
	LL_GPIO_PIN_12,LL_GPIO_PIN_13,LL_GPIO_PIN_14,LL_GPIO_PIN_15
} ;

//Private function declaration   私有函数申明
static void GPIO_PinModeSet(uint8 u8_Port ,	uint8 u8_Pin ,uint32 u32_Mode,uint8 u8_Value) ;
static uint32_t GPIO_PinInGet(uint8 u8_Port ,	uint8 u8_Pin) ;


//Public function definition   公共函数定义
void DrvGpio_Init(void)
{
	LL_PWR_EnablePUA(LL_PWR_PUPD_IO0);
	LL_PWR_EnablePUA(LL_PWR_PUPD_IO1);
	LL_PWR_EnablePDA(LL_PWR_PUPD_IO2);
	LL_PWR_EnablePUA(LL_PWR_PUPD_IO3);
	LL_PWR_EnablePDA(LL_PWR_PUPD_IO8);
	LL_PWR_EnablePDA(LL_PWR_PUPD_IO9);
	LL_PWR_EnablePDA(LL_PWR_PUPD_IO10);
	LL_PWR_EnablePDA(LL_PWR_PUPD_IO11); 
	
	LL_PWR_EnablePDB(LL_PWR_PUPD_IO0);
	LL_PWR_EnablePUB(LL_PWR_PUPD_IO1);
	LL_PWR_EnablePUB(LL_PWR_PUPD_IO2);
	LL_PWR_EnablePDB(LL_PWR_PUPD_IO3);
	LL_PWR_EnablePUB(LL_PWR_PUPD_IO4);
	LL_PWR_EnablePDB(LL_PWR_PUPD_IO5);
	LL_PWR_EnablePDB(LL_PWR_PUPD_IO6);
	LL_PWR_EnablePUB(LL_PWR_PUPD_IO7);
	LL_PWR_EnablePDB(LL_PWR_PUPD_IO14);
	LL_PWR_EnablePUB(LL_PWR_PUPD_IO15);
	
	DrvGpio_Set(LED_1_PIN ,MODE_OUTPUT_NO ,0) ;
	DrvGpio_Set(LED_2_PIN ,MODE_OUTPUT_NO ,1) ;
	DrvGpio_Set(LED_3_PIN ,MODE_OUTPUT_NO ,1) ;
}


void DrvGpio_Set
(
uint8 u8_Channel,
uint32 u32_Mode,
uint8 u8_Value
)
{
	uint8 u8_Port = (u8_Channel & DRV_GPIO_MASK_PORT) >> 4;
	uint8 u8_Pin = u8_Channel & DRV_GPIO_MASK_PIN;
	GPIO_PinModeSet(u8_Port ,u8_Pin ,u32_Mode,u8_Value) ;
}

uint8 DrvGpio_InGet
(
uint8 u8_Channel
)
{
	uint8 u8_Port = (u8_Channel & DRV_GPIO_MASK_PORT) >> 4;
	uint8 u8_Pin = u8_Channel & DRV_GPIO_MASK_PIN;
	return GPIO_PinInGet(u8_Port ,u8_Pin) ;
}




//Private function definition   私有函数定义

static void GPIO_PinModeSet(uint8 u8_Port ,	uint8 u8_Pin ,uint32 u32_Mode ,uint8 u8_Value)
{
	LL_AHB_EnableClock(AHB_PERIPH[u8_Port]) ;
	LL_GPIO_SetPinSpeed(Port[u8_Port], Pin[u8_Pin], LL_GPIO_SPEED_FREQ_HIGH);
	LL_GPIO_SetPinOutputType(Port[u8_Port], Pin[u8_Pin], LL_GPIO_OUTPUT_PUSHPULL);
	
	if(u32_Mode == MODE_INPUT_NO)
	{	
		LL_GPIO_SetPinMode(Port[u8_Port], Pin[u8_Pin], LL_GPIO_MODE_INPUT);
		LL_GPIO_SetPinPull(Port[u8_Port], Pin[u8_Pin], LL_GPIO_PULL_NO);
	}
	else if(u32_Mode == MODE_INPUT_UP)
	{
		LL_GPIO_SetPinMode(Port[u8_Port], Pin[u8_Pin], LL_GPIO_MODE_INPUT);
		LL_GPIO_SetPinPull(Port[u8_Port], Pin[u8_Pin], LL_GPIO_PULL_UP);
	}
	else if(u32_Mode == MODE_INPUT_DOWN)
	{
		LL_GPIO_SetPinMode(Port[u8_Port], Pin[u8_Pin], LL_GPIO_MODE_INPUT);
		LL_GPIO_SetPinPull(Port[u8_Port], Pin[u8_Pin], LL_GPIO_PULL_DOWN);
	}
	else if(u32_Mode == MODE_OUTPUT_NO)
	{
		LL_GPIO_SetPinMode(Port[u8_Port], Pin[u8_Pin], LL_GPIO_MODE_OUTPUT);
		LL_GPIO_SetPinPull(Port[u8_Port], Pin[u8_Pin], LL_GPIO_PULL_NO);
	}
	else if(u32_Mode == MODE_OUTPUT_UP)
	{
		LL_GPIO_SetPinMode(Port[u8_Port], Pin[u8_Pin], LL_GPIO_MODE_OUTPUT);
		LL_GPIO_SetPinPull(Port[u8_Port], Pin[u8_Pin], LL_GPIO_PULL_UP);
	}
	else if(u32_Mode == MODE_OUTPUT_DOWN)
	{
		LL_GPIO_SetPinMode(Port[u8_Port], Pin[u8_Pin], LL_GPIO_MODE_OUTPUT);
		LL_GPIO_SetPinPull(Port[u8_Port], Pin[u8_Pin], LL_GPIO_PULL_DOWN);
	}
	else if(u32_Mode == MODE_ANALO)
	{
		LL_GPIO_SetPinMode(Port[u8_Port], Pin[u8_Pin], LL_GPIO_MODE_ANALOG);
		LL_GPIO_SetPinPull(Port[u8_Port], Pin[u8_Pin], LL_GPIO_PULL_NO);
	}
	if(u32_Mode > MODE_ANALO)
	{
		if(u8_Value)
		{
			LL_GPIO_SetOutputPin(Port[u8_Port], Pin[u8_Pin]) ;
		}
		else
		{
			LL_GPIO_ResetOutputPin(Port[u8_Port], Pin[u8_Pin]) ;
		}
	}
}
static uint32_t GPIO_PinInGet(uint8 u8_Port ,	uint8 u8_Pin)
{
	return LL_GPIO_IsInputPinSet(Port[u8_Port], Pin[u8_Pin]);
}











